import {_decorator, Component, Node, RigidBody, Vec3, v3,macro, find} from 'cc';
import {JoyStickController} from "db://assets/scripts/ui/joystick/JoyStickController";
import {AudioPaths} from "db://assets/scripts/common/AudioPaths";
import {PlayerAnimationType} from "db://assets/scripts/game/role/player/PlayerAnimationType";
import {BaseInfoConverter} from "db://assets/scripts/data/converter/BaseInfoConverter";
import {BaseEnum} from "db://assets/scripts/game/BaseEnum";
import {BaseInfo} from "db://assets/scripts/data/model/BaseInfo";
import {GameManager} from "db://assets/scripts/game/GameManager";
import {CSVManager} from "db://assets/scripts/common/CSVManager";
import {FightTipEnum} from "db://assets/scripts/ui/common/FightTipEnum";
import {PoolManager} from "db://assets/scripts/common/PoolManager";
import {PlayerModelController} from "db://assets/scripts/game/role/player/PlayerModelController";
import {EffectManager} from "db://assets/scripts/common/EffectManager";
import {AudioManager} from "db://assets/scripts/common/AudioManager";
import {PlayerBloodBarController} from "db://assets/scripts/game/role/player/PlayerBloodBarController";
import {ResourceUtils} from "db://assets/scripts/common/ResourceUtils";
import {PlayerModelManager} from "db://assets/scripts/game/role/player/PlayerModelManager";
import {FightTipController} from "db://assets/scripts/ui/common/FightTipController";

const {ccclass, property} = _decorator;

@ccclass('PlayerManager')
export class PlayerManager extends Component {
    private _joyStickCom: JoyStickController;

    private _speed: number = 5;

    private _rigidBody: RigidBody = null;

    // private _ndRunSmokeEffect: Node = null!;//烟雾特效

    private _attackState: boolean = false;


    // private _arrowPos: Vec3 = new Vec3();//箭初始化位置

    private _player_blood: Node = null;

    public playerBaseInfo: BaseInfo;//玩家在base.csv的基础数据


    public set isDie(v: boolean) {
        this._isDie = v;

        if (this._isDie) {
            // this._showDie();
        }
    }

    public get isDie() {
        return this._isDie;
    }

    //是否拥有形态技能
    public isArrowDouble: boolean = false;//是否拥有技能：弓箭双重射击
    public isArrowPenetrate: boolean = false;//是否拥有技能：弓箭穿透射击
    public isArrowContinuous: boolean = false;//是否拥有技能：连续射击

    //是否拥有buff技能
    public isArrowIce: boolean = false;//是否拥有技能：冰冻
    public isArrowFire: boolean = false;//是否拥有技能：灼烧

    //是否拥有触发技能
    public isBloodthirsty: boolean = false;//是否拥有技能：嗜血
    public isArrowLightning: boolean = false;//是否拥有技能： 闪电
    public isArrowLaunch: boolean = false;//是否拥有技能：弹射

    //当前"数值技能"值
    public curAttackPower: number = 20;//当前攻击力
    public curDefensePower: number = 1;//当前防御力
    public curAttackSpeed: number = 1;//当前攻击速度
    public curDodgeRate: number = 0;//当前闪避率
    public curCriticalHitRate: number = 0;//当前暴击率，0为不暴击
    public curCriticalHitDamage: number = 0;//当前暴击伤害
    public curHpLimit: number = 0;//当前玩家生命值上限（这个是上限，是生命上限，不是当前生命值）
    public set curMoveSpeed(v: number) {
        this._curMoveSpeed = v;
        // this.scriptCharacterRigid.initSpeed(v);
    }

    public get curMoveSpeed() {
        return this._curMoveSpeed;
    }

    //技能数组
    private _arrFormChangeSkill: string[] = [];//玩家当前拥有的形态变化技能10x
    private _arrValueChangeSkill: string[] = [];//玩家数值变化技能20x
    private _arrBuffSkill: string[] = [];//玩家buff技能30x
    private _arrTriggerSkill: string[] = [];//玩家触发技能40x

    private _hp: number = 0;//玩家当前生命值
    private _isDie: boolean = false;//主角是否阵亡
    private _horizontal: number = 0;//水平移动距离
    private _vertical: number = 0;//垂直移动距离
    private _targetAngle: Vec3 = new Vec3();//目标旋转角度
    private _curAngleY: number = 0;//当前Y分量旋转角度
    private targetNode: Node = null!;//目标小怪
    private _throwArrowSpeed: number = 30;//弓箭速30
    private _arrowPos: Vec3 = new Vec3();//箭初始化位置
    private _bloodTipOffsetPos: Vec3 = new Vec3(-10, 150, 0);//血量提示和玩家间距
    private _playerMonsterOffset: Vec3 = new Vec3();//小怪和玩家间距
    private _oriPlayerPos: Vec3 = new Vec3(0, 1.7, 0);//玩家初始世界坐标
    private _oriPlayerScale: Vec3 = new Vec3(4, 4, 4);//玩家初始缩放倍数
    private _oriPlayerAngle: Vec3 = new Vec3(0, -90, 0);//玩家初始角度
    private _curAngle_1: Vec3 = new Vec3()//当前玩家旋转的角度
    private _curAngle_2: Vec3 = new Vec3();//玩家角度
    private _rotateDirection: Vec3 = new Vec3();//旋转方向
    private _ndRunSmokeEffect: Node = null!;//烟雾特效
    private _originAngle: Vec3 = new Vec3(0, -90, 0);//玩家开始角度
    private _tempAngle: Vec3 = new Vec3();//临时变量，玩家角度
    private _forWard: Vec3 = new Vec3();//朝向
    private _range: number = 0.01;//
    private _curMoveSpeed: number = 0;//当前玩家移动速度
    private _curBlood: number = 0;//当前血量
    private _rotateInterval: number = 0.3;//检查停止移动后是否还在旋转
    private _arrArrowPreload: string[] = [];


    private static instance: PlayerManager;

    public static getInstance() {
        return this.instance;
    }

    onLoad() {
        PlayerManager.instance = this;
    }

    start() {

        this.init();

        this._rigidBody = this.getComponent(RigidBody);

        this.playRunSmoke();

        this.initBloodBar();

        // this.scheduleOnce(()=>
        // {
        //     this._player_blood.getComponent(PlayerBlood).refreshBlood(-100);
        // },3);
    }


    /**
     * 玩家扣血
     *
     * @param {*} baseInfo 敌人基础信息
     * @return {*}
     * @memberof Player
     */
    public reduceBlood(baseInfo: any) {
        if (this.isDie) {
            return;
        }

        AudioManager.getInstance().playSound(AudioPaths.hitPlayerSound);

        if (Math.random() > this.playerBaseInfo.dodgeRate) {
            //扣血
            let tipType = FightTipEnum.REDUCE_BLOOD;
            //敌人伤害
            let damage = baseInfo.attackPower * GameManager.getInstance().chapter.attackAddition * (1 - this.playerBaseInfo.defensePower / (this.playerBaseInfo.defensePower + 400));
            let isCriticalHit = Math.random() <= baseInfo.criticalHitRate;//是否暴击
            if (isCriticalHit) {
                damage = damage * baseInfo.criticalHitDamage;
                tipType = FightTipEnum.CRITICAL_HIT;
            }
            // UIManager.instance.showBloodTips(this, tipType, -damage, this._bloodTipOffsetPos);
            // this.scriptBloodBar.refreshBlood(-damage);

            this.showBloodTips(this, tipType, -damage, this._bloodTipOffsetPos)
            this._player_blood.getComponent(PlayerBloodBarController).refreshBlood(-damage);
        }
    }

    /**
     * 展示血量提示
     */
    public showBloodTips(scriptParent: any, type: number, bloodNum: number, offset: Vec3, callback?: Function) {
        ResourceUtils.loadUIPrefab('common/fightTip').then(prefab => {
            let ndTip = <Node>PoolManager.getInstance().getNode(prefab, <Node>find("Canvas"));
            let pos = GameManager.getInstance().mainCamera.convertToUINode(scriptParent.node.worldPosition, find('Canvas') as Node) as Vec3;
            pos.add(offset);
            ndTip.setPosition(pos);

            let fightTipController = ndTip.getComponent(FightTipController);
            fightTipController.show(scriptParent, type, bloodNum, callback);
        });
    }

    public init() {
        // this.isMoving = false;
        // this.isDie = false;
        // this.isPlayRotate = false;

        // this.isArrowDouble = false;
        // this.isArrowPenetrate = false;
        // this.isArrowContinuous = false;
        // this.isArrowIce = false;
        // this.isArrowFire = false;
        // this.isBloodthirsty = false;
        // this.isArrowLightning = false;
        // this.isArrowLaunch = false;

        // this._horizontal = 0;
        // this._vertical = 0;

        // this._curBlood = 0;
        // this.targetNode = null!;

        // this.scriptCharacterRigid = this.node.getComponent(CharacterRigid) as CharacterRigid;

        //获取玩家基础数据
        let baseCSV = CSVManager.getInstance().getTable("base");
        let baseInfos = BaseInfoConverter.convertFromCSV(baseCSV);
        this.playerBaseInfo = baseInfos.find(bseInfo => bseInfo.ID === BaseEnum.PLAYER_01);

        if (this.playerBaseInfo) {
            //设置玩家大小
            this._oriPlayerScale.set(this.playerBaseInfo.scale);
            this.node.setScale(this._oriPlayerScale);

            // this.resetPlayerWorPos();

            //设置角度
            this._oriPlayerAngle.set(this.playerBaseInfo.angle);
            this.node.eulerAngles = this._oriPlayerAngle;

            this.curAttackPower = this.playerBaseInfo.attackPower;
            this.curDefensePower = this.playerBaseInfo.defensePower;
            this.curAttackSpeed = this.playerBaseInfo.attackSpeed;
            this.curMoveSpeed = this.playerBaseInfo.moveSpeed;
            this.curDodgeRate = this.playerBaseInfo.dodgeRate;
            this.curCriticalHitRate = this.playerBaseInfo.criticalHitRate;
            this.curCriticalHitDamage = this.playerBaseInfo.criticalHitDamage;
            this.curHpLimit = this.playerBaseInfo.hp;

            this._hp = this.playerBaseInfo.hp;
        }

        // this._parsePlayerSkill(true);

        // console.log("###加载血条1");
        // //展示血条
        // UIManager.instance.showPlayerBloodBar(this, this._hp, this._hp, ()=>{
        //     // if (GameManager.isTesting) {
        //     //     this.addBlood(2000, true);
        //     // }
        // }, this._bloodTipOffsetPos);

        // this.scriptPlayerModel.playAni(Constant.PLAYER_ANI_TYPE.IDLE, true);

        // this.scriptPlayerModel.init();

        // this.rigidComPlayer.clearState();
    }


    private initBloodBar(): void {
        ResourceUtils.loadUIPrefab('fight/playerBloodBar').then(prefab => {
            let ndBloodBar = PoolManager.getInstance().getNode(prefab, find("Canvas") as Node) as Node;
            ndBloodBar.setSiblingIndex(0);
            this._player_blood = ndBloodBar;

            let playerBloodBarController = ndBloodBar.getComponent(PlayerBloodBarController);
            playerBloodBarController.setTotalBlood(this._hp);

            // let scriptBloodBar = ndBloodBar.getComponent(PlayerBloodBar) as PlayerBloodBar;
            // scriptParent.scriptBloodBar = scriptBloodBar;
            // scriptBloodBar.show(scriptParent, totalBlood, curBlood, offsetPos, scale, callback);
        });
    }


    public throwArrowToEnemy(): void {
        this._initArrow("arrowSingle");
    }

    /**
     * 初始化箭
     *
     * @private
     * @param {string} arrowName
     * @memberof Player
     */
    private _initArrow(arrowName: string) {
        ResourceUtils.loadModel(`weapon/arrow02/${arrowName}`).then((prefab: any) => {

            let ndArrow = PoolManager.getInstance().getNode(prefab, this.node.parent as Node) as Node;
            let playerWorPos = this.node.worldPosition;
            this._arrowPos.set(playerWorPos.x, 3, playerWorPos.z);

            // if (GameManager.isTesting) {
            //     this._arrowPos.set(playerWorPos.x, -3, playerWorPos.z);
            // }

            ndArrow.setWorldPosition(this._arrowPos);
            ndArrow.eulerAngles = this.node.eulerAngles;

            // ndArrow.children.forEach((ndArrowItem: Node)=>{
            //     let scriptArrowItem = ndArrowItem.getComponent(Arrow) as Arrow;
            //     scriptArrowItem.init(this._throwArrowSpeed, this.node.worldPosition);
            // })

            // //播放箭的音效
            // let isHasIce = GameManager.scriptPlayer.isArrowIce;
            // let isHasFire = GameManager.scriptPlayer.isArrowFire;
            // let isHasLightning = GameManager.scriptPlayer.isArrowLightning;

            // if (isHasIce || isHasFire || isHasLightning) {
            //     if (isHasIce) {
            //         AudioManager.instance.playSound(Constant.SOUND.ICE);
            //     }

            //     if (isHasFire) {
            //         AudioManager.instance.playSound(Constant.SOUND.FIRE);
            //     }

            //     if (isHasLightning) {
            //         AudioManager.instance.playSound(Constant.SOUND.LIGHTNING);
            //     }
            // } else {
            //     AudioManager.instance.playSound(Constant.SOUND.LOOSE);
            // }
        })
    }

    /**
     * 奔跑的时候加个烟雾
     *
     * @memberof Player
     */
    public playRunSmoke() {
        if (!this._ndRunSmokeEffect) {
            ResourceUtils.loadEffect("runSmoke/runSmoke").then((pf: any) => {
                this._ndRunSmokeEffect = PoolManager.getInstance().getNode(pf, this.node);
                this._ndRunSmokeEffect.active = true;
                EffectManager.getInstance().playParticle(this._ndRunSmokeEffect);
            });
        } else {
            this._ndRunSmokeEffect.active = true;
            EffectManager.getInstance().playParticle(this._ndRunSmokeEffect);
        }
    }


    update(deltaTime: number) {
        // todo 正常情况下打开
        // this._joyStickCom = GameScene.instance.joyStickCom;
        if (!this._joyStickCom) {
            return;
        }


        if (this._joyStickCom.isMoving == true) {

            // todo 正常情况下打开
            // GameScene.instance.isGameStart = true;

            // console.log("angle>>>>>>",this._joyStickCom.angle);

            let radian = this._joyStickCom.angle * macro.RAD;

            // // // Math.cos(radian) = 临边/斜边;
            // let speed_x = Math.cos(radian) * this._speed * deltaTime;
            // let speed_y = Math.sin(radian) * this._speed * deltaTime;

            // let pos = this.node.getWorldPosition();
            // pos.x += speed_y;
            // pos.z += speed_x;
            // this.node.setWorldPosition(pos);


            let speed_x = Math.cos(radian) * this._speed;
            let speed_y = Math.sin(radian) * this._speed;
            this._rigidBody.setLinearVelocity(v3(speed_y, 0, speed_x));


            let rotation: Vec3 = this.node.eulerAngles;
            this.node.setRotationFromEuler(v3(rotation.x, this._joyStickCom.angle + 180, rotation.x))

            this._attackState = false;
            //播放攻击动画
            this.getComponentInChildren(PlayerModelController).playAni(PlayerAnimationType.RUN, true, () => {
                // if (!this.scriptPlayerModel.isRunning) {
                //     this._attackMonster();
                // }
            });

        } else {
            this._rigidBody.clearVelocity();

            // todo 正常情况下打开
            /*if (GameScene.instance.isGameStart == false) {
                // 播放攻击动画
                this.getComponentInChildren(PlayerModelController).playAni(PlayerAnimationType.IDLE, true, () => {
                    // if (!this.scriptPlayerModel.isRunning) {
                    //     this._attackMonster();
                    // }
                });
            } else {
                this._attackMonster();

                // 瞄准
                // let targetNode = find("Monster/aula");
                // this.node.lookAt(targetNode.getWorldPosition());
            }*/
        }

    }


    /**
     * 向怪物方向攻击
     */
    private _attackMonster() {

        if (this._attackState == true) {
            return;
        }
        this.targetNode = GameManager.getInstance().gameGetMonsterProxy.getNearestMonster();

        if (this.targetNode == null) {

            this.getComponentInChildren(PlayerModelManager).playAni(PlayerAnimationType.IDLE, false, () => {

            });


        } else {

            console.log("====", this.targetNode)

            this.node.lookAt(this.targetNode.worldPosition);

            //   if (!this.targetNode || this.isDie) {
            //       return;
            //   }

            // // if (!this.targetNode || this.isDie) {
            // //     return;
            // // }

            // // this._moveToTargetWorPos(this.targetNode.worldPosition);

            // this.isMoving = false;

            // // //播放攻击动画
            this._attackState = true;
            this.getComponentInChildren(PlayerModelManager).playAni(PlayerAnimationType.ATTACK, false, () => {
                this._attackState = false;
                // if (!this.scriptPlayerModel.isRunning) {
                //     this._attackMonster();
                // }
            });
        }

    }

}

